import 'package:built_collection/built_collection.dart';
import 'package:mobile_app.core/core/domain/entities/settings/pronunciation_settings_data.dart';
import 'package:mobile_app.core/core/domain/entities/tts_voice.dart';
import 'package:mobile_app.core/core/domain/helpers/get_tts_voice/helper.dart';
import 'package:mobile_app.core/core/domain/helpers/is_tts_voice_available/helper.dart';
import 'package:mobile_app.core/core/domain/helpers/pick_available_tts_voice/helper.dart';
import 'package:mobile_app.core/core/domain/helpers/update_pronunciation_settings_data_from_voice/helper.dart';

abstract class MakePronunciationSettingsDataConsistent {
  PronunciationSettingsData call({
    required PronunciationSettingsData pronunciationSettingsData,
    required BuiltList<TtsVoice> availableAmVoices,
    required BuiltList<TtsVoice> availableBrVoices,
  });
}

class MakePronunciationSettingsDataConsistentImpl
    implements MakePronunciationSettingsDataConsistent {
  const MakePronunciationSettingsDataConsistentImpl({
    required IsTtsVoiceAvailable isTtsVoiceAvailable,
    required GetTtsVoice getTtsVoice,
    required PickAvailableTtsVoice pickAvailableTtsVoice,
    required UpdatePronunciationSettingsDataFromVoice updatePronunciationSettingsDataFromVoice,
  })  : _isTtsVoiceAvailable = isTtsVoiceAvailable,
        _getTtsVoice = getTtsVoice,
        _pickAvailableTtsVoice = pickAvailableTtsVoice,
        _updatePronunciationSettingsDataFromVoice = updatePronunciationSettingsDataFromVoice;

  final IsTtsVoiceAvailable _isTtsVoiceAvailable;
  final GetTtsVoice _getTtsVoice;
  final PickAvailableTtsVoice _pickAvailableTtsVoice;
  final UpdatePronunciationSettingsDataFromVoice _updatePronunciationSettingsDataFromVoice;

  @override
  PronunciationSettingsData call({
    required PronunciationSettingsData pronunciationSettingsData,
    required BuiltList<TtsVoice> availableAmVoices,
    required BuiltList<TtsVoice> availableBrVoices,
  }) {
    final currentVoice = _getTtsVoice(
      dialect: pronunciationSettingsData.dialect,
      amVoiceTitle: pronunciationSettingsData.amVoiceTitle,
      brVoiceTitle: pronunciationSettingsData.brVoiceTitle,
    );

    if (currentVoice != null) {
      final currentVoiceAvailable = _isTtsVoiceAvailable(
        voice: currentVoice,
        availableAmVoices: availableAmVoices,
        availableBrVoices: availableBrVoices,
      );

      if (currentVoiceAvailable) {
        return pronunciationSettingsData;
      }
    }

    final updatedVoice = _pickAvailableTtsVoice(
      dialect: pronunciationSettingsData.dialect,
      availableAmVoices: availableAmVoices,
      availableBrVoices: availableBrVoices,
    );

    final updatedPronunciationSettingsData = _updatePronunciationSettingsDataFromVoice(
      pronunciationSettingsData: pronunciationSettingsData,
      updatedVoice: updatedVoice,
    );

    return updatedPronunciationSettingsData;
  }
}
